package com.mine.redis.util.service;

import com.mine.redis.util.bean.BlogDO;
import com.mine.redis.util.bean.ScrollPage;
import com.mine.redis.util.mapper.BlogMapper;
import com.mine.redis.util.mapper.FollowMapper;
import com.mine.redis.util.utils.id.RedisIdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * @author weixiao
 * @date 2024/8/19 15:25
 */
@Service
public class BlogService {

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private FollowMapper followMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisIdWorker redisIdWorker;

    public void post(BlogDO blog) {
        // 1.将博客保存至数据库
        int blogId = blogMapper.insert(blog);
        // 2.采用推的方式，将博客推送至粉丝的收件箱
        if (blogId > 0) {
            List<Integer> fanIds = followMapper.getFans(blog.getUserId());
            long score = redisIdWorker.nextId("blog:score:");
            for (Integer fanId : fanIds) {
                stringRedisTemplate.opsForZSet().add("feed:" + fanId, blog.getId().toString(), score);
            }
        }
    }

    public ScrollPage<BlogDO> getBlogList(Integer userId, Long lastScore, Integer offset) {
        if (lastScore == null || lastScore == -1) {
            lastScore = Long.MAX_VALUE;
            offset = 0;
        }
        Set<ZSetOperations.TypedTuple<String>> typedTuples =
                stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores("feed:" + userId, 0, lastScore, offset, 3);
        List<BlogDO> blogList = new ArrayList<>();
        ScrollPage<BlogDO> res = new ScrollPage<>();
        if (!CollectionUtils.isEmpty(typedTuples)) {
            List<Integer> blogIdList = new ArrayList<>(typedTuples.size());
            Long newLastScore = 0L;
            for (ZSetOperations.TypedTuple<String> tuple : typedTuples) {
                blogIdList.add(Integer.parseInt(tuple.getValue()));
                newLastScore = tuple.getScore().longValue();
            }
            blogList = blogMapper.selectByIds(blogIdList);
            res.setLastScore(newLastScore);
        }
        res.setData(blogList);
        res.setOffset(1);
        return res;
    }
}
